package com.sukaiyi.giteeideaplugin.mainwindow;

import cn.hutool.json.JSONObject;
import com.intellij.icons.AllIcons;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.IconLoader;
import com.intellij.ui.components.JBLabel;
import com.sukaiyi.giteeideaplugin.mainwindow.repodetailtabbedpane.*;
import com.sukaiyi.giteeideaplugin.utils.BrowseUtils;
import com.sukaiyi.giteejavaapi.common.Gitee;
import com.sukaiyi.giteejavaapi.common.Params;
import icons.PluginIcons;
import org.jetbrains.annotations.NotNull;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Comparator;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class RepoDetailWindow implements ActionListener {

    private static final Logger logger = Logger.getInstance(RepoDetailWindow.class);

    private final JSONObject repo;

    private JPanel content;
    private JPanel titlePanel;
    private JBLabel titleLabel;
    private JBLabel languageLabel;
    private JBLabel licenseLabel;
    private JBLabel recommendLabel;
    private JButton starButton;
    private JButton watchButton;
    private JButton forkButton;
    // 选项卡
    private JTabbedPane tabbedPane;
    private CodeTabbedPane codePane;
    private IssuesTabbedPane issuesPane;
    private PullRequestTabbedPane pullRequestPane;
    private ServiceTabbedPane servicePane;
    private ReadmeTabbedPane readmePane;
    private JPanel actionBarPanel;

    public RepoDetailWindow(JSONObject repo) {
        this.repo = repo;

        titleLabel.setIcon(repo.getBool("private", false) ? PluginIcons.LOCK_DARK : PluginIcons.REPO_DARK);
        titleLabel.setText(repo.getStr("full_name"));
        languageLabel.setText(repo.getStr("language"));
        licenseLabel.setText(repo.getStr("license"));
        recommendLabel.setIcon(PluginIcons.RECOMMEND);
        recommendLabel.setVisible(repo.getBool("recommend", false));

        boolean stared = repo.getBool("stared");
        starButton.setIcon(stared ? PluginIcons.STAR : IconLoader.getDisabledIcon(PluginIcons.STAR));
        starButton.setText((stared ? "Unstar" : "Star") + " " + repo.getStr("stargazers_count"));
        starButton.addActionListener(this);
        boolean watched = repo.getBool("watched");
        watchButton.setIcon(watched ? PluginIcons.WATCH : IconLoader.getDisabledIcon(PluginIcons.WATCH));
        watchButton.setText((watched ? "Unwatch" : "Watch") + " " + repo.getStr("watchers_count"));
        watchButton.addActionListener(this);
        forkButton.setIcon(PluginIcons.FORK);
        forkButton.setText("Fork " + repo.getStr("forks_count"));
        forkButton.addActionListener(this);

        tabbedPane.addChangeListener(changeEvent -> {
//            Component selectedComponent = tabbedPane.getSelectedComponent();
//            if (selectedComponent == codeTabbedPanel) {
//                refreshBranch();
//            }
        });
        setupTabbedPaneTitle(
                Stream.of(readmePane, codePane, issuesPane, pullRequestPane, servicePane)
                        .sorted(Comparator.comparingInt(RepoDetailPane::getIndex))
                        .collect(Collectors.toList())
        );

        DefaultActionGroup actionGroup = new DefaultActionGroup();
        // clone
        actionGroup.add(new AnAction(AllIcons.Actions.TraceInto) {
            @Override
            public void actionPerformed(@NotNull AnActionEvent e) {
                new CloneRepoWindow(repo).show();
            }
        });
        // 浏览器中打开
        actionGroup.add(new AnAction(AllIcons.General.Web) {
            @Override
            public void actionPerformed(@NotNull AnActionEvent e) {
                BrowseUtils.open(repo.getStr("html_url"));
            }
        });
        ActionToolbar actionToolbar = ActionManager.getInstance().createActionToolbar("Group Toolbar", actionGroup, true);
        actionBarPanel.add(actionToolbar.getComponent());
    }

    private void setupTabbedPaneTitle(List<RepoDetailPane> panes) {
        for (int i = 0; i < panes.size(); i++) {
            RepoDetailPane pane = panes.get(i);
            JComponent component = pane.getTitleComponent();
            String title = pane.getTitle();
            Icon icon = pane.getIcon();

            if (component == null) {
                component = createTabComponent(icon, title);
            }
            tabbedPane.setTabComponentAt(i, component);
        }
    }

    public void createUIComponents() {
        readmePane = new ReadmeTabbedPane(repo);
        codePane = new CodeTabbedPane(repo);
        issuesPane = new IssuesTabbedPane(repo);
        pullRequestPane = new PullRequestTabbedPane(repo);
        servicePane = new ServiceTabbedPane(repo);
    }

    private JComponent createTabComponent(Icon icon, String title) {
        JPanel container = new JPanel();
        FlowLayout flowLayout = (FlowLayout) container.getLayout();
        flowLayout.setHgap(10);
        container.setOpaque(false);
        JBLabel label = new JBLabel(title);
        label.setIcon(icon);
        container.add(label);
        return container;
    }

    public JPanel getContent() {
        return content;
    }

    @Override
    public void actionPerformed(ActionEvent actionEvent) {
        Object source = actionEvent.getSource();
        if (source == starButton) {
            boolean stared = !repo.getBool("stared");
            repo.compute("stargazers_count", (key, old) -> {
                int oldInt = Optional.ofNullable(old).map(e -> (Integer) e).orElse(0);
                return stared ? oldInt + 1 : oldInt - 1;
            });
            repo.putOpt("stared", stared);
            starButton.setIcon(stared ? PluginIcons.STAR : IconLoader.getDisabledIcon(PluginIcons.STAR));
            starButton.setText((stared ? "Unstar" : "Star") + " " + repo.getStr("stargazers_count"));
            Gitee.getInstance().invoke(
                    stared ? "putV5UserStarredOwnerRepo" : "deleteV5UserStarredOwnerRepo",
                    Params.create()
                            .set("owner", (String) repo.getByPath("namespace.path"))
                            .set("repo", repo.getStr("path"))
            );
        } else if (source == watchButton) {
            boolean watched = !repo.getBool("watched");
            repo.compute("watchers_count", (key, old) -> {
                int oldInt = Optional.ofNullable(old).map(e -> (Integer) e).orElse(0);
                return watched ? oldInt + 1 : oldInt - 1;
            });
            repo.putOpt("watched", watched);
            watchButton.setIcon(watched ? PluginIcons.WATCH : IconLoader.getDisabledIcon(PluginIcons.WATCH));
            watchButton.setText((watched ? "Unwatch" : "Watch") + " " + repo.getStr("watchers_count"));
            Params params = Params.create()
                    .set("owner", (String) repo.getByPath("namespace.path"))
                    .set("repo", repo.getStr("path"));
            if (watched) {
                params.set("watch_type", "watching");
            }
            Gitee.getInstance().invoke(
                    watched ? "putV5UserSubscriptionsOwnerRepo" : "deleteV5UserSubscriptionsOwnerRepo",
                    params
            );
        } else if (source == forkButton) {
            new ForkRepoWindow(repo).showAndGet();
        }
    }

}
